﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PK2;
using System.ComponentModel.Composition;
using System.Configuration;
using Twitterizer;

namespace TwitterPlugin
{
    [Export(typeof(IPKPlugin))]
    public class PKTwitter: IPKPlugin
    {
        private const string _token = "twitter";
        private Configuration _cfg;
        private OAuthTokens oauthTokens;
        private TwitterUser user;
        private List<PKCommand> _commands;
        private List<PKCompletionSet> _completionSets;

        private IProcrastinationKit _pk;

        public void Initialize(IProcrastinationKit pk, Configuration config)
        {
            _pk = pk;
            _cfg = config;

            LoadCommands();
                       
            //TODO: fix login and token loading
            if (RememberMe && IsUserAuthenticated)
            {
                LoadOAuthTokens();
                LoadCompletionSets();
            }


        }

        private void LoadCommands()
        {
            _commands = new List<PKCommand>();
            _commands.Add(new PKCommand{ DisplayText = "tweet", InsertionText = "tweet", Description = "Post a tweet in the user's timeline" });
            _commands.Add(new PKCommand { DisplayText = "login", InsertionText = "login", Description = "Login into twitter. This command doesnt take parameters" });
            _commands.Add(new PKCommand { DisplayText = "logout", InsertionText = "logout", Description = "Logout from twitter. This command doesnt take parameters" });
        }

        private void LoadCompletionSets()
        {
            _completionSets = new List<PKCompletionSet>();

            PKCompletionSet csContacts = new PKCompletionSet
            {
                DisplayName = "Contacts",
                LaunchToken = '@'
            };

            var myFriends = TwitterFriendship.Friends(this.oauthTokens);
            List<PKCompletionItem> items = new List<PKCompletionItem>();
            while (myFriends != null)
            {
                //TODO: Make this async. takes tooo long to get all the followers
                items.AddRange((from f in myFriends.ResponseObject
                                select new PKCompletionItem
                                {
                                    DisplayText = "@" + f.ScreenName,
                                    InsertionText = f.ScreenName,
                                    Description = f.ScreenName + ". "+ f.Description
                                }));
                myFriends = myFriends.ResponseObject.NextPage();
            }
            csContacts.Items = items.ToArray();

            _completionSets.Add(csContacts);
        }

        public void CommandExecuted(PKCommandEventArgs e)
        {
            try
            {
                switch (e.Command.DisplayText)
                {
                    case "tweet":
                        if (!this.IsUserAuthenticated)
                        {
                            _pk.SetTextInTheStatusBar("The user is not loged in :P");
                            return;
                        }

                        TwitterStatusAsync.Update(this.oauthTokens, e.Arguments.Trim(), null, new TimeSpan(0, 0, 10), updateResponse =>
                        {
                            if (updateResponse.Result == RequestResult.Success)
                                _pk.SetTextInTheStatusBar("Tweet posted :)");
                            else
                                _pk.SetTextInTheStatusBar(updateResponse.ErrorMessage);
                        }); 
                        break;
                    case "login":
                        frmLogin frm = new frmLogin(_cfg);
                        frm.ShowDialog();

                        if (!this.IsUserAuthenticated)
                        {
                            _pk.SetTextInTheStatusBar("The the user was not loged in :(");
                            return;
                        }

                        LoadOAuthTokens();
                        LoadCompletionSets();
                        break;
                    case "logout":

                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                _pk.SetTextInTheStatusBar(ex.Message);
            }
        }

        public string Token
        {
            get { return _token; }
        }

        public string Description
        {
            get { return "Provides interaction with Twitter"; }
        }

        private bool IsUserAuthenticated
        {
            get
            {
                return !string.IsNullOrEmpty(_cfg.AppSettings.Settings["Twitterizer.Desktop.AccessToken"].Value);
            }
        }

        private bool RememberMe
        {
            get
            {
                return Convert.ToBoolean(_cfg.AppSettings.Settings["Twitterizer.Desktop.RememberMe"].Value);
            }

        }

        private void LoadOAuthTokens()
        {
           
            this.oauthTokens = new OAuthTokens()
            {
                AccessToken = _cfg.AppSettings.Settings["Twitterizer.Desktop.AccessToken"].Value,
                AccessTokenSecret = _cfg.AppSettings.Settings["Twitterizer.Desktop.AccessTokenSecret"].Value,
                ConsumerKey = _cfg.AppSettings.Settings["Twitterizer.Desktop.ConsumerKey"].Value,
                ConsumerSecret = _cfg.AppSettings.Settings["Twitterizer.Desktop.ConsumerSecret"].Value
            };
            decimal userId = decimal.Parse(_cfg.AppSettings.Settings["Twitterizer.Desktop.UserId"].Value);

            try
            {
                this.user = TwitterUser.Show(oauthTokens, userId).ResponseObject;
                _pk.SetTextInTheStatusBar(string.Format("You are logged in Twitter as {0}", this.user.ScreenName));
            }
            catch (System.Exception ex)
            {
                _pk.SetTextInTheStatusBar(ex.Message);
            }
        }
        
        public PKCommand[] Commands
        {
            get { return _commands.ToArray(); }
        }

        public PKCompletionSet[] CompletionSets
        {
            get 
            {
                if (!this.IsUserAuthenticated || _completionSets == null)
                    return new PKCompletionSet[0];

                return _completionSets.ToArray(); 
            }
        }
                
    }
}
